package com.yuantu.judiciary.dao;

import com.yuantu.judiciary.model.domain.VipOrderDO;
import com.yuantu.judiciary.model.enums.OrganizationType;
import com.yuantu.judiciary.model.enums.PayState;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import java.sql.Timestamp;
import java.util.List;

/**
 * 套餐订单
 *
 * @author syw
 * @since 2023-08-14
 **/
public interface IVipOrderDao extends JpaRepository<VipOrderDO, Long> {

    VipOrderDO findOrderByIdAndCreatorIdAndDeletedFalse(Long id, Long creatorId);

    VipOrderDO findOrderByTradeNoAndDeletedFalse(String tradeNo);

    Page<VipOrderDO> findOrderByCreatorIdAndDeletedFalse(Long creatorId, Pageable pageable);

    List<VipOrderDO> findByCreatorIdInAndDeletedFalse(List<Long> creatorId);



    List<VipOrderDO> findByCreatorIdInAndDeletedFalseAndPayState(List<Long> creatorId, PayState payState);

    VipOrderDO findOrderByIdAndDeletedFalse(Long id);

    List<VipOrderDO> findOrderByOrganizationIdAndPayStateAndDeletedFalse(Long organizationId, PayState payState);

    List<VipOrderDO> findOrderByIdInAndDeletedFalse(List<Long> ids);

    @Query("select o from VipOrderDO o  " +
            "where o.deleted = false " +
            "and (:tradeNo is null or :tradeNo = '' or o.tradeNo like concat('%', :tradeNo, '%')) " +
            "and (:orderSource is null or (:orderSource = 1 and o.prepayId is not null) or (:orderSource = 2 and o.prepayId is null)) " +
            "and (:organizationType is null or o.orgType = :organizationType) ")
    Page<VipOrderDO> findOrderByTradeNoAndOrgType(String tradeNo, OrganizationType organizationType,
                                                  Integer orderSource,
                                                  Pageable pageable);

    @Query("select o.payTime as payTime, o.vipId as vipId, o.vipName as vipName, od.totalPrice as totalPrice, " +
            "od.unitPrice as unitPrice, od.duration as duration, od.queryTotalNum as queryTotalNum, " +
            "od.accountNum as accountNum, od.username as username, od.phone as phone " +
            "from VipOrderDO o " +
            "left join VipOrderDetailDO od on o.id = od.orderId " +
            "where o.organizationId = :organizationId and o.payState = 'SUCCESS' " +
            "and o.deleted = false and od.deleted = false ")
    Page<OrgVipInfo> getOrgVipInfo(Long organizationId, Pageable pageable);

    List<VipOrderDO> findOrderInfosByPayStateAndDeletedFalse(PayState payState);

    List<VipOrderDO> findByCreatorIdInAndDeletedFalseAndPayStateAndDiscountCodeIdIsNull(List<Long> accountIds, PayState payState);

    List<VipOrderDO> findOrderInfosByPayStateAndDiscountCodeIdAndDeletedFalse(PayState payState, Long discountCodeId);

    List<VipOrderDO> findOrderInfosByDiscountCodeIdAndDeletedFalse(Long discountCodeId);

    List<VipOrderDO> findOrderInfosByDiscountCodeIdInAndPayStateAndDeletedFalse(List<Long> discountCodeIds, PayState payState);

    interface OrgVipInfo {
        Timestamp getPayTime();
        Long getVipId();
        String getVipName();
        Double getTotalPrice();
        Double getUnitPrice();
        Integer getDuration();
        Integer getQueryTotalNum();
        Integer getAccountNum();
        String getUsername();
        String getPhone();
    }

    @Query("select o from VipOrderDO o " +
            "where o.payState = 'SUCCESS' and o.deleted = false " +
            "and (:startTime is null or o.payTime >= :startTime) " +
            "and (:endTime is null or o.payTime <= :endTime) ")
    List<VipOrderDO> findOrderByPayStateAndDeletedFalse(Timestamp startTime, Timestamp endTime);

    List<VipOrderDO> findAllByCreatorIdAndPayStateAndVipIdInAndDeletedFalse(
            Long creatorId, PayState state,List<Long> vipIds
    );

}
